/*
 * Box.h
 *
 *  Created on: 12.2.2013
 *      Author: Travis
 */

#pragma once

#ifdef _WIN32 
#include <windows.h> 
#endif

#include "../dataTypes/Cube.h"
#include "../Terrain.h"
#include "../Water.h"
#include <glm/glm.hpp>
#include <vector>
#include "../scene/World.h"
#include "../console/globalConsole.h"
#include "../objects/Entity.h"

#define COUNT_OF_CHILDREN 4

const float MAX_Y = 30.0;
const float WATER_OFFSET = 0.2;

namespace Octree
{

class Box
{
public:
	Box(int _start_x, int _start_y, int _size, int _nesting, float _step,
			Terrain::Terrain *_terrain, Water *_w);
	virtual ~Box();
	// delete box
	void deleteBox();

	// draw only visible parts of terrain
	// and water if water is true
	// return Minimum of visible area
	float drawVisible(GLuint shadowMap, int shaderType, bool drawWiredBox,
			bool waterVisible, bool terVisible, GLuint refTexture,
			GLuint refractionTexture);

	// update local part of terrain
	// set cube in witch change was performed
	void updateLocal(DataTypes::Cube updateLocality, glm::vec3 pos);

	// inserting entity
	void insertEntity(Entity *insert);

	// draw only entities in current box
	// id are stored in entityID vector
	void drawEntity(int shaderType);
private:
	// set points in collision cube
	void setCube(float high);
	// create 8 cubes by dividing this box
	void sexFunction();

	void updateEntityYPos();

	// use terrain class for generating VBO for part of terrain
	void getTerrainVBO();

	// use water class for generating VBO for part of terrain 
	void getWaterVBO();

	glm::vec2 getMinMaxYEntity();
	glm::vec2 MinMaxTerrain;

	// buffers
	GLuint vertex, normal, uv, element;
	// count of vertices after indexing
	GLuint isize;

	// buffers for water surface
	GLuint vertexW, normalW, uvW, elementW;
	// count of vertices after indexing for water surface
	GLuint isizeW;

	// box dimensions
	int start_x, start_y, size, nesting;

	float step;

	// Collision cube
	DataTypes::Cube *cube;

	// terrain pointer
	Terrain::Terrain *terrain;

	// water pointer
	Water *water;

	// children
	Box *children[COUNT_OF_CHILDREN];

	// vector of entities in box
	std::vector<Entity*> entityID;
};

// vector holding pointers to actual visible boxes
// of terrain, units and water
// when scene is up to date render engine don't
// searching for visible boxes but use stored pointers
// useful only for storing leaves
extern std::vector<Box*> visibleBoxes;

// true when visibility was already found
// root Box call only children stored in visibleBoxes
// vector
// false means that visibility should be found again
extern bool actualVisible;
extern bool actualVisibleEnt;

// root nesting level
// need to be set first!!!
extern int rootNesting;

extern float lastMinValue;

// set root nesting
void setRootNesting(int n);

// update scene when camera is mooving
void updateScene();
//----------------------------------------------------

}

